
package net.swa.dewei.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.type.StandardBasicTypes;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import net.swa.dewei.beans.entity.Merchants;
import net.swa.dewei.beans.entity.MerchantsLog;
import net.swa.dewei.service.MerchantsService;
import net.swa.system.dao.HibernateDaoSupport;
import net.swa.util.BuzConst;
import net.swa.util.DateUtils;
import net.swa.util.JsonResult;
import net.swa.util.geography.GqueryUtil;
import net.swa.util.geography.VoSquare;

@Service("merchantsService")
public class MerchantsServiceImpl extends HibernateDaoSupport implements MerchantsService
{

    private final Logger log = Logger.getLogger(MerchantsServiceImpl.class);

    @Override
    public JsonResult<Merchants> queryPageList(Long fuwuzhanId , String fuwuzhanName , String name , String merchType , String merchStatus , int currentPage , int pageSize , String orderBy , String orderType)
    {
        if (log.isDebugEnabled())
        {
            log.debug("传入参数 fuwuZhanId is " + fuwuzhanId + " ,fuwuzhanName is " + fuwuzhanName + ", currentPage is " + currentPage + ",pageSize is " + pageSize + ",orderBy is " + orderBy);
        }
        JsonResult<Merchants> json = new JsonResult<Merchants>();
        StringBuilder sql = new StringBuilder();
        StringBuilder countsql = new StringBuilder();
        Query query = null;
        countsql.append("select count(1) as counNum  from t_Merchants m LEFT JOIN t_fuwuzhan f on f.id=m.fuwuzhanId where 1=1 ");
        sql.append("select m.id,m.actiAtt,m.actiBeginTime,m.actiEndTime,m.address,m.city,m.crateDate,m.deldata,m.detailInfo,m.fuwuzhanId,m.imageUrl,m.invaliDates,m.keyWords,m.latitude,m.longitude,m.lxr,m.lxrTel,m.name,m.no,m.wxNo,m.province,m.status,m.town, m.type,m.updateDate,m.useRules,m.allowTime,m.wxid,m.reason,m.wxNick,m.xiajiaReason ,f.`name` fwzName from t_Merchants m LEFT JOIN t_fuwuzhan f on f.id=m.fuwuzhanId where 1=1 ");

        sql.append(" and m.deldata=:deldata  ");
        countsql.append(" and m.deldata=:deldata ");

        if (null != fuwuzhanId)
        {
            sql.append(" and m.fuwuzhanId= :fuwuzhanId ");
            countsql.append(" and m.fuwuzhanId= :fuwuzhanId ");
        }
        else if (!StringUtils.isBlank(fuwuzhanName))
        {
            sql.append(" and f.name like :fuwuzhanName");
            countsql.append(" and f.name like :fuwuzhanName");
        }
        if (!StringUtils.isBlank(name))
        {
            sql.append(" and m.name  like :name");
            countsql.append(" and m.name  like :name");
        }

        if (!StringUtils.isBlank(merchType))
        {
            sql.append(" and m.type=:merchType ");
            countsql.append(" and m.type=:merchType ");
        }
        if (!StringUtils.isBlank(merchStatus))
        {
            sql.append(" and m.status=:merchStatus ");
            countsql.append(" and m.status=:merchStatus ");
        }
        if (!StringUtils.isBlank(orderBy))
        {
            sql.append("order by " + orderBy);
            if (!StringUtils.isBlank(orderType))
            {
                sql.append("  " + orderType);
            }
        }
        //        query = getCurrentSession().createSQLQuery(sql.toString()).addScalar("id", StandardBasicTypes.LONG).addScalar("actiAtt", StandardBasicTypes.STRING).addScalar("actiBeginTime", StandardBasicTypes.STRING).addScalar("actiEndTime", StandardBasicTypes.STRING).addScalar("address", StandardBasicTypes.STRING).addScalar("city", StandardBasicTypes.STRING).addScalar("crateDate", StandardBasicTypes.STRING).addScalar("deldata", StandardBasicTypes.BOOLEAN).addScalar("detailInfo", StandardBasicTypes.STRING).addScalar(
        //                "fuwuzhanId", StandardBasicTypes.LONG).addScalar("imageUrl", StandardBasicTypes.STRING).addScalar("invaliDates", StandardBasicTypes.STRING).addScalar("keyWords", StandardBasicTypes.STRING).addScalar("latitude", StandardBasicTypes.DOUBLE).addScalar("longitude", StandardBasicTypes.DOUBLE).addScalar("lxr", StandardBasicTypes.STRING).addScalar("lxrTel", StandardBasicTypes.STRING).addScalar("name", StandardBasicTypes.STRING).addScalar("no", StandardBasicTypes.STRING).addScalar("province",
        //                StandardBasicTypes.STRING).addScalar("status", StandardBasicTypes.STRING).addScalar("town", StandardBasicTypes.STRING).addScalar("type", StandardBasicTypes.STRING).addScalar("updateDate", StandardBasicTypes.STRING).addScalar("useRules", StandardBasicTypes.STRING).addScalar("wxid", StandardBasicTypes.STRING).addScalar("reason", StandardBasicTypes.STRING).addScalar("wxNick", StandardBasicTypes.STRING).addScalar("xiajiaReason", StandardBasicTypes.STRING).addScalar("fwzName", StandardBasicTypes.STRING)
        //                .setResultTransformer(Transformers.aliasToBean(Merchants.class));

        query = getCurrentSession().createSQLQuery(sql.toString()).addEntity(Merchants.class);

        query.setBoolean("deldata", false);
        if (null != fuwuzhanId)
        {
            query.setLong("fuwuzhanId", fuwuzhanId);
        }
        else if (!StringUtils.isBlank(fuwuzhanName))
        {
            query.setString("fuwuzhanName", "%" + fuwuzhanName + "%");
        }
        if (!StringUtils.isBlank(name))
        {
            query.setString("name", "%" + name + "%");
        }

        if (!StringUtils.isBlank(merchType))
        {
            query.setString("merchType", merchType);
        }
        if (!StringUtils.isBlank(merchStatus))
        {
            query.setString("merchStatus", merchStatus);
        }

        if (pageSize > 0)
        {
            int from = (currentPage - 1) * pageSize;
            query.setFirstResult(from);
            query.setMaxResults(pageSize);
        }
        List<Merchants> list = query.list();
        query = getCurrentSession().createSQLQuery(countsql.toString()).addScalar("counNum", StandardBasicTypes.INTEGER);
        query.setBoolean("deldata", false);
        if (null != fuwuzhanId)
        {
            query.setLong("fuwuzhanId", fuwuzhanId);
        }
        else if (!StringUtils.isBlank(fuwuzhanName))
        {
            query.setString("fuwuzhanName", "%" + fuwuzhanName + "%");
        }
        if (!StringUtils.isBlank(name))
        {
            query.setString("name", "%" + name + "%");
        }
        if (!StringUtils.isBlank(merchType))
        {
            query.setString("merchType", merchType);
        }
        if (!StringUtils.isBlank(merchStatus))
        {
            query.setString("merchStatus", merchStatus);
        }
        if (pageSize > 0)
        {
            int totalCount = (Integer) query.uniqueResult();
            int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
            json.setTotalSize(totalCount);
            json.setTotalPage(totalPage);
            json.setPageSize(pageSize);
            json.setCurrentPage(currentPage);
        }
        json.setResult(list);
        return json;
    }

    @Override
    public JsonResult<String> addModel(Merchants model)
    {
        Session session = getCurrentSession();
        JsonResult<String> json = new JsonResult<String>();
        model.setCrateDate(DateUtils.getCurrDate(null));

        model.setStatus(BuzConst.MERVHANTS_STATUS0);
        session.save(model);

        json.setSuccess(true);
        json.setMessage("");
        return json;
    }

    @Override
    public JsonResult<String> updateModel(Merchants model)
    {
        Session session = getCurrentSession();
        JsonResult<String> json = new JsonResult<String>();
        model.setUpdateDate(DateUtils.getCurrDate(null));
        session.update(model);

        json.setSuccess(true);
        json.setMessage("");
        return json;
    }

    @Override
    public JsonResult<String> updateCheckModel(Merchants model)
    {
        Session session = getCurrentSession();
        JsonResult<String> json = new JsonResult<String>();
        Merchants m = (Merchants) session.get(Merchants.class, model.getId());
        if (null != m)
        {
            MerchantsLog log = new MerchantsLog();
            BeanUtils.copyProperties(m, log);
            log.setId(null);
            log.setLogTime(DateUtils.getCurrDate(null));
            session.save(log);
            m.setStatus(model.getStatus());
            m.setReason(model.getReason());

            m.setXiajiaReason(model.getXiajiaReason());

            m.setUpdateDate(DateUtils.getCurrDate(null));
            session.update(m);
            json.setSuccess(true);
            json.setMessage("");
        }
        else
        {
            json.setSuccess(false);
            json.setMessage("查询失败");
        }
        return json;
    }

    // 求两点相聚距离
    private double calcfunction(double lat , double lng , Merchants menDian)
    {
        double EARTH_RADIUS = 6378.137;// 地球半径
        double radLat1 = rad(lat);
        double radLat2 = rad(menDian.getLatitude());
        double a = radLat1 - radLat2;
        double b = rad(lng) - rad(menDian.getLongitude());
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10;

        log.debug("两点间距离：" + s);
        return s;// Math.pow((menDian.getLatitude() - lat), 2) +
        // Math.pow(menDian.getLongitude() - lng, 2);
    }

    private double rad(double d)
    {
        return d * Math.PI / 180.0;
    }

    @Override
    public List<Merchants> queryByLatLng(Double lat , Double lng , int d)
    {
        if (0 == d)
        {
            d = 20;
        }
        final VoSquare v = GqueryUtil.querySquarePoint(lng, lat, d);
        //查询有效的门店
        String hql = "from Merchants where  status=" + BuzConst.STATUS_CHECK_YES + " and deldata=" + false + " and longitude>=:minLng and longitude<=:maxLng and  latitude>=:minLat AND latitude<=:maxLat ";

        Query query = getCurrentSession().createQuery(hql);
        query.setDouble("minLng", v.getMinLng());
        query.setDouble("maxLng", v.getMaxLng());
        query.setDouble("minLat", v.getMinLat());
        query.setDouble("maxLat", v.getMaxLat());
        List<Merchants> list = query.list();
        List<Merchants> list2 = null;
        if (null != list && list.size() > 0)
        {
            for (int i = 0; i < list.size(); i++)
            {
                double dis = calcfunction(lat, lng, list.get(i));

                Merchants o = list.get(i);
                log.debug("商家：" + o.getName() + ",距离您" + dis + ",您的经纬度：" + lat + "," + lng + ";商家的经纬度：" + o.getLatitude() + "," + o.getLongitude());
                o.setDoubleDistance(dis);
                if (dis >= 1000)
                {
                    java.text.DecimalFormat df = new java.text.DecimalFormat("0.0");
                    o.setDistance(df.format(dis / 1000) + "公里");
                }
                else if (dis > 100)
                {
                    java.text.DecimalFormat df = new java.text.DecimalFormat("0");
                    o.setDistance(df.format(dis / 100) + "00米");
                }
                else
                {
                    o.setDistance("100米");
                }
            }

            Collections.sort(list);
            log.debug("查询结果如下：");
            list2 = new ArrayList<Merchants>();
            for (int i = 0; i < 5 && i < list.size(); i++)
            {
                if (i == 0)
                {
                    list.get(i).setTuijian(true);
                }
                else
                {
                    list.get(i).setTuijian(false);
                }
                log.debug("商家：" + list.get(i).getName() + ",\n距离您" + list.get(i).getDistance() + ",\n门店经纬度：" + list.get(i).getLatitude() + "," + list.get(i).getLongitude());
                list2.add(list.get(i));
            }
        }
        return list2;
    }

    @Override
    public boolean batchUpdate(Long[] ids)
    {

        for (int i = 0; i < ids.length; i++)
        {
            Query query = null;
            query = getCurrentSession().createQuery("update Merchants set deldata=:deldata  where id=:id ");
            query.setBoolean("deldata", true);
            query.setLong("id", ids[i]);
            query.executeUpdate();
        }
        return true;
    }

    @Override
    public Merchants queryById(Long id)
    {
        Merchants m = (Merchants) getCurrentSession().get(Merchants.class, id);
        return m;
    }

}